﻿using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Runtime.CompilerServices;
using System.Linq;
using System.Text;
using pokerServer.ProtHandlers;
using ConnectionControl;

using System.Threading;

namespace pokerServer.GameManagment.GameTools
{
	public class TableManage
	{
		public static ConcurrentBag<Table> tables = new ConcurrentBag<Table>();
		public ConnectionManag cm;
		private int numT = 0;

		public TableManage(ConnectionManag cm)
		{
			this.cm = cm;
			tables.Add(new Table(cm, 1111, 2000, 40000, 100, 200, 2, 9));
			tables.Add(new Table(cm, 1112, 4000, 80000, 200, 400, 2, 9));
			tables.Add(new Table(cm, 1113, 4000, 80000, 200, 400, 2, 9));
			tables.Add(new Table(cm, 1114, 20000, 400000, 1000, 2000, 2, 9));
			tables.Add(new Table(cm, 1115, 20000, 400000, 2000, 4000, 2, 9));

		}
		public Table findTable(uint tableid) {
			foreach (Table t in tables) {
				if (t.TableID == tableid) {
					Console.WriteLine("Table --------->" + t);
					return t;
				}
			}
			
			throw new TableIsntExistsTableException();
		}

		public string getTableList() {

			string tablelist = "";
			foreach (Table t in tables) {
				tablelist+= string.Format("<TabledID:{0}><MaxBuy:{1}><MinBuy:{2}>,", t.TableID, t.BuyInMax, t.BuyInMin);
			}
			return string.Format("TableList {0}", tablelist);
		}

		public void startTables() {

			Thread trd;
			foreach (Table t in tables) {
				trd = new Thread(new ThreadStart(t.TableWorker));
				try {
					trd.Start();
					trd.IsBackground = true;
				}
				catch (Exception e) {
					Console.WriteLine("Error while openning table [{0}] Exception [{1}]", t, e);
				}
			}
			
		}
		public void stopTables() {
			Console.WriteLine("Closing tables");
			foreach (Table t in tables) {
				t.TableRunning = false;
				if (t.GameState != GameEngine.GameStates.NotStarted && t.GameState != GameEngine.GameStates.EndGame) {
					t.endGame();
				}
			}
			Console.WriteLine("End closing tables");
		}

		/*
		[MethodImpl(MethodImplOptions.Synchronized)]
		public Boolean joinTable(int id, ClientConnection c,out TableErrors t)
		{
			if (id >= 0)
			{
				if (tables.ElementAt(id) != null)
				{
					checkClearTable(c.conName);
					tables.ElementAt(id).addSpec(c,out t);
					c.tableID = id;
					return true;
				}
					
			}
			t = TableErrors.ERR_TableNotExist;
			return false;
		}

		[MethodImpl(MethodImplOptions.Synchronized)]
		public Boolean joinSeat(int id, int seatId, ClientConnection c, out TableErrors t)
		{
			if(id >= 0 && seatId >= 0)
			{
				if(tables.ElementAt(id) != null)
				{
					if (!tables.ElementAt(id).isFull())
					{
						if (!tables.ElementAt(id).seatTaken(seatId))
						{
							tables.ElementAt(id).addPlayer(c.conName, seatId);
							t = TableErrors.ERR_TableSeatJoined;
							c.seatID = seatId;
							this.sendMsgToTable(id, "UserList " + tables.ElementAt(id).playerList());
							return true;
						}
						else
						{
							t = TableErrors.ERR_SeatTaken;
							return false;
						}
					}
					else
					{
						t = TableErrors.ERR_TableFull;
						return false;
					}
				}
				else
				{
					t = TableErrors.ERR_TableNotExist;
					return false;
				}
				
			}
			t = TableErrors.ERR_TableSeatNotExist;
			return false;
		}

		[MethodImpl(MethodImplOptions.Synchronized)]
		public bool leaveSeat(int tid, int sid, ClientConnection c, out TableErrors t)
		{
			if (tid >= 0 && sid >= 0)
			{
				if (tables.ElementAt(tid) != null)
				{
					if (tables.ElementAt(tid).seatTaken(sid))
					{
						tables.ElementAt(tid).backtoSpec(c.conName, sid);
						c.seatID = -1;
						this.sendMsgToTable(tid, "UserList " + tables.ElementAt(tid).playerList());
						t = TableErrors.ERR_LeftSeat;
						return true;
					}
					else
						t = TableErrors.ERR_SeatNotTaken;
					return false;
				}
				else 
					t = TableErrors.ERR_TableNotExist;
				return false;
			}
			t = TableErrors.ERR_TableSeatNotExist;
			return false;
		}
		[MethodImpl(MethodImplOptions.Synchronized)]
		private void sendMsgToTable(int tableid, String message)
		{
			if (tableid >= 0)
			{
				tables.ElementAt(tableid).sendAll(message);
			}

		}
		[MethodImpl(MethodImplOptions.Synchronized)]
		public bool leaveTable(int tid,ClientConnection c, out TableErrors t)
		{
			if (tid >= 0)
			{
				if (tables.ElementAt(tid) != null)
				{
					int index = -1;
					if ((index = tables.ElementAt(tid).inSeat(c.conName)) > -1)
					{
						tables.ElementAt(tid).leaveTable(c.conName, index);

					}
					else
					{
						tables.ElementAt(tid).leaveTable(c.conName);						
					}
					c.seatID = -1;
					c.tableID = -1;
					t = TableErrors.ERR_LeftTable;
					return true;
				}
				else
					t = TableErrors.ERR_TableNotExist;
				return false;
				
			}
			t = TableErrors.ERR_TableSeatNotExist;
			return false;
		}

		[MethodImpl(MethodImplOptions.Synchronized)]
		private void checkClearTable(String name)
		{
			foreach (Table t in tables)
			{
				int i = -1;
				if ((i = t.inSeat(name)) > -1)
					t.leaveTable(name, i);
			}
		}

		[MethodImpl(MethodImplOptions.Synchronized)]
		public String getTableList()
		{
			String s = "TableList,";
			for (int i = 0; i < tables.Count; i++)
			{
				s += "<TabledID:" + i + "><MaxBuy:" + tables.ElementAt(i).maxBuyin + "><MinBuy:" + tables.ElementAt(i).minBuyin + ">,";
			}
			return s;
		}
		*/

		[MethodImpl(MethodImplOptions.Synchronized)]
		public void shutDown()
		{
			
			for (int i = 0; i < tables.Count; i++)
			{
				Table t;
				tables.TryTake(out t);
				//t.shutDown();
				System.Threading.Thread.Sleep(100);	
			}
		}

		/*
		[MethodImpl(MethodImplOptions.Synchronized)]
		public String getPlayerList(int tableId)
		{
			if (tableId >= 0)
			{
				return tables.ElementAt(tableId).playerList();
			}
			return "No Such Table";
		}
		*/
	}
}
